interface LinkedNode {
  value: number|null
  next: LinkedNode
}

class LinkedList {
  public head: LinkedNode
  
  public constructor () {
    this.head = {
      value: null,
      next: null
    }
  }

  public getElem (i: number) {
    let currentNode = this.head.next
    let currentIndex = 1
    while (currentIndex < i && currentNode.next) {
      currentNode = currentNode.next
      currentIndex++
    }
    if (currentNode && currentIndex == i) {
      return currentNode.value
    } else {
      throw "ERROR"
    }
  }

  public display () {
    let currentNode = this.head
    while (currentNode = currentNode.next) {
      console.log(currentNode.value)
    }
  }

  public listInsert (i: number, data: number) {
    let currentNode = this.head.next
    let currentIndex = 1
    let prevNode = this.head
    while (currentIndex < i && currentNode) {
      prevNode = currentNode
      currentNode = currentNode.next
      currentIndex++
    }

    if (currentIndex == i) {
      let node: LinkedNode = {
        next: currentNode,
        value: data
      }
      prevNode.next = node
    } else {
      throw new Error(`index ${i} not existed`)
    }
  }
}

const list = new LinkedList()
list.listInsert(1, 1)
list.listInsert(2, 2)
list.listInsert(4, 1)
list.display()
